home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / TECHFUN.ZIP / XMODE.ASM < prev    next >
Assembly Source File  |  1995-05-23  |  38KB  |  1,422 lines

  1. .MODEL HUGE, C
  2.  
  3. .486
  4.  
  5. .CODE
  6.  
  7. ; XMODE routines by Kaos (a.k.a. Bruno Carlos) of Black Magic
  8.  
  9. ; Mode 0 -> 320x200 4 pages
  10. ; Mode 1 -> 320x240 3 pages
  11. ; Mode 2 -> 320x400 2 pages
  12. ; Mode 3 -> 320x480 1 page
  13. ; Mode 4 -> 360x200 3 pages
  14. ; Mode 5 -> 360x240 3 pages
  15. ; Mode 6 -> 360x400 1 page
  16. ; Mode 7 -> 360x480 1 page
  17.  
  18. ; If you use this code in any of your
  19. ; productions give us the proper credits...
  20.  
  21. ;****************************************************************************
  22.  
  23. out_16  MACRO register, value
  24.  
  25.     ifdifi <register>,<dx>          ; if dx not setup
  26.     mov dx,register                 ; then select register
  27.     endif
  28.     ifdifi <value>,<ax>             ; if ax not setup
  29.     mov ax,value                    ; then get data value
  30.     endif
  31.     out dx,ax                       ; set i/o register(s)
  32. ENDM
  33.  
  34. ;****************************************************************************
  35.  
  36. out_8   MACRO register, value
  37.  
  38.     ifdifi <register>,<dx>          ; if dx not setup
  39.     mov dx,register                 ; then select register
  40.     endif
  41.     ifdifi <value>,<al>             ; if al not setup
  42.     mov al,value                    ; then get data value
  43.     endif
  44.     out dx,al                       ; set i/o register
  45. ENDM
  46.  
  47. ;******************************************************************************
  48.  
  49. vwait     MACRO
  50.     local    Vertout,Vertin
  51.  
  52.     mov       dx,03DAh
  53.  Vertout:
  54.     in        al,dx
  55.     test      al,8
  56.     jnz       Vertout      ; wait Until out of vertical retrace
  57.  Vertin:
  58.     in        al,dx
  59.     test      al,8
  60.     jz        Vertin       ; wait Until inside vertical retrace
  61. ENDM
  62.  
  63. ;******************************************************************************
  64.  
  65. hwait     MACRO
  66.     local    Horzout,Horzin
  67.  
  68.     mov       dx,03DAh
  69.  Horzout:
  70.     in        al,dx
  71.     test      al,1
  72.     jnz       Horzout      ; wait Until out of horizontal retrace
  73.  Horzin:
  74.     in        al,dx
  75.     test      al,1
  76.     jz        Horzin       ; wait Until inside horizontal retrace
  77. ENDM
  78.  
  79. ;****************************************************************************
  80.  
  81. xmode:
  82.     dw  offset X320x200
  83.     dw  offset X320x240
  84.     dw  offset X320x400
  85.     dw  offset X320x480
  86.     dw  offset X360x200
  87.     dw  offset X360x240
  88.     dw  offset X360x400
  89.     dw  offset X360x480
  90.  
  91. ;****************************************************************************
  92.  
  93. X320x200:
  94.  
  95.     db  063h        ; 400 scan lines & 25 mhz clock
  96.     dw  05f00h      ; horz total
  97.     dw  04f01h      ; horz displayed
  98.     dw  05002h      ; start horz blanking
  99.     dw  08203h      ; end horz blanking
  100.     dw  05404h      ; start h sync
  101.     dw  08005h      ; end h sync
  102.     dw  0bf06h      ; vertical total
  103.     dw  01f07h      ; overflow
  104.     dw  09c10h      ; v sync start
  105.     dw  08e11h      ; v sync end/prot cr0 cr7
  106.     dw  08f12h      ; vertical displayed
  107.     dw  09615h      ; v blank start
  108.     dw  0b916h      ; v blank end
  109.     dw  04109h      ; cell height (2 scan lines)
  110.     dw  00014h      ; dword mode off
  111.     dw  0e317h      ; turn on byte mode
  112.     dw  16000/4     ; page size (dwords)
  113.     dw  320         ; xmax
  114.     dw  200         ; ymax
  115.     dw  0        ; page 1 offset
  116.     dw  16000    ; page 2 offset
  117.     dw  32000    ; page 3 offset
  118.     dw  48000    ; page 4 offset
  119.  
  120. ;****************************************************************************
  121.  
  122. X320x240:
  123.  
  124.     db  0e3h        ; 480 scan lines & 25 mhz clock
  125.     dw  05f00h      ; horz total
  126.     dw  04f01h      ; horz displayed
  127.     dw  05002h      ; start horz blanking
  128.     dw  08203h      ; end horz blanking
  129.     dw  05404h      ; start h sync
  130.     dw  08005h      ; end h sync
  131.     dw  00d06h      ; vertical total
  132.     dw  03e07h      ; overflow
  133.     dw  0ea10h      ; v sync start
  134.     dw  08c11h      ; v sync end/prot cr0 cr7
  135.     dw  0df12h      ; vertical displayed
  136.     dw  0e715h      ; v blank start
  137.     dw  00616h      ; v blank end
  138.     dw  04109h      ; cell height (2 scan lines)
  139.     dw  00014h      ; dword mode off
  140.     dw  0e317h      ; turn on byte mode
  141.     dw  19200/4     ; page size (dwords)
  142.     dw  320         ; xmax
  143.     dw  240         ; ymax
  144.     dw  0        ; page 1 offset
  145.     dw  19200    ; page 2 offset
  146.     dw  38400    ; page 3 offset
  147.     dw  0           ; page 4 offset (same as page 1)
  148.  
  149. ;****************************************************************************
  150.  
  151. X320x400:
  152.  
  153.     db  063h        ; 400 scan lines & 25 mhz clock
  154.     dw  05f00h      ; horz total
  155.     dw  04f01h      ; horz displayed
  156.     dw  05002h      ; start horz blanking
  157.     dw  08203h      ; end horz blanking
  158.     dw  05404h      ; start h sync
  159.     dw  08005h      ; end h sync
  160.     dw  0bf06h      ; vertical total
  161.     dw  01f07h      ; overflow
  162.     dw  09c10h      ; v sync start
  163.     dw  08e11h      ; v sync end/prot cr0 cr7
  164.     dw  08f12h      ; vertical displayed
  165.     dw  09615h      ; v blank start
  166.     dw  0b916h      ; v blank end
  167.     dw  04009h      ; cell height (1 scan line)
  168.     dw  00014h      ; dword mode off
  169.     dw  0e317h      ; turn on byte mode
  170.     dw  32000/4     ; page size (dwords)
  171.     dw  320         ; xmax
  172.     dw  400         ; ymax
  173.     dw  0        ; page 1 offset
  174.     dw  32000    ; page 2 offset
  175.     dw  0        ; page 3 offset (same as page 1)
  176.     dw  32000    ; page 4 offset (same as page 2)
  177.  
  178. ;****************************************************************************
  179.  
  180. X320x480:
  181.  
  182.     db  0e3h        ; 480 scan lines & 25 mhz clock
  183.     dw  05f00h      ; horz total
  184.     dw  04f01h      ; horz displayed
  185.     dw  05002h      ; start horz blanking
  186.     dw  08203h      ; end horz blanking
  187.     dw  05404h      ; start h sync
  188.     dw  08005h      ; end h sync
  189.     dw  00d06h      ; vertical total
  190.     dw  03e07h      ; overflow
  191.     dw  0ea10h      ; v sync start
  192.     dw  08c11h      ; v sync end/prot cr0 cr7
  193.     dw  0df12h      ; vertical displayed
  194.     dw  0e715h      ; v blank start
  195.     dw  00616h      ; v blank end
  196.     dw  04009h      ; cell height (1 scan line)
  197.     dw  00014h      ; dword mode off
  198.     dw  0e317h      ; turn on byte mode
  199.     dw  38400/4     ; page size (dwords)
  200.     dw  320         ; xmax
  201.     dw  480         ; ymax
  202.     dw  0        ; page 1 offset
  203.     dw  0        ; page 2 offset (same as page 1)
  204.     dw  0        ; page 3 offset (same as page 1)
  205.     dw  0           ; page 4 offset (same as page 1)
  206.  
  207. ;****************************************************************************
  208.  
  209. X360x200:
  210.  
  211.     db  067h        ; 400 scan lines & 28 mhz clock
  212.     dw  06b00h      ; horz total
  213.     dw  05901h      ; horz displayed
  214.     dw  05a02h      ; start horz blanking
  215.     dw  08e03h      ; end horz blanking
  216.     dw  05e04h      ; start h sync
  217.     dw  08a05h      ; end h sync
  218.     dw  0bf06h      ; vertical total
  219.     dw  01f07h      ; overflow
  220.     dw  09c10h      ; v sync start
  221.     dw  08e11h      ; v sync end/prot cr0 cr7
  222.     dw  08f12h      ; vertical displayed
  223.     dw  09615h      ; v blank start
  224.     dw  0b916h      ; v blank end
  225.     dw  04109h      ; cell height (2 scan lines)
  226.     dw  00014h      ; dword mode off
  227.     dw  0e317h      ; turn on byte mode
  228.     dw  18000/4     ; page size (dwords)
  229.     dw  360         ; xmax
  230.     dw  200         ; ymax
  231.     dw  0        ; page 1 offset
  232.     dw  18000    ; page 2 offset
  233.     dw  36000    ; page 3 offset
  234.     dw  0        ; page 4 offset (same as page 1)
  235.  
  236. ;****************************************************************************
  237.  
  238. X360x240:
  239.  
  240.     db  0e7h        ; 480 scan lines & 28 mhz clock
  241.     dw  06b00h      ; horz total
  242.     dw  05901h      ; horz displayed
  243.     dw  05a02h      ; start horz blanking
  244.     dw  08e03h      ; end horz blanking
  245.     dw  05e04h      ; start h sync
  246.     dw  08a05h      ; end h sync
  247.     dw  00d06h      ; vertical total
  248.     dw  03e07h      ; overflow
  249.     dw  0ea10h      ; v sync start
  250.     dw  08c11h      ; v sync end/prot cr0 cr7
  251.     dw  0df12h      ; vertical displayed
  252.     dw  0e715h      ; v blank start
  253.     dw  00616h      ; v blank end
  254.     dw  04109h      ; cell height (2 scan lines)
  255.     dw  00014h      ; dword mode off
  256.     dw  0e317h      ; turn on byte mode
  257.     dw  21600/4     ; page size (dwords)
  258.     dw  360         ; xmax
  259.     dw  240         ; ymax
  260.     dw  0        ; page 1 offset
  261.     dw  21600    ; page 2 offset
  262.     dw  43200    ; page 3 offset
  263.     dw  0        ; page 4 offset (same as page 1)
  264.  
  265. ;****************************************************************************
  266.  
  267. X360x400:
  268.  
  269.     db  067h        ; 400 scan lines & 28 mhz clock
  270.     dw  06b00h      ; horz total
  271.     dw  05901h      ; horz displayed
  272.     dw  05a02h      ; start horz blanking
  273.     dw  08e03h      ; end horz blanking
  274.     dw  05e04h      ; start h sync
  275.     dw  08a05h      ; end h sync
  276.     dw  0bf06h      ; vertical total
  277.     dw  01f07h      ; overflow
  278.     dw  09c10h      ; v sync start
  279.     dw  08e11h      ; v sync end/prot cr0 cr7
  280.     dw  08f12h      ; vertical displayed
  281.     dw  09615h      ; v blank start
  282.     dw  0b916h      ; v blank end
  283.     dw  04009h      ; cell height (1 scan line)
  284.     dw  00014h      ; dword mode off
  285.     dw  0e317h      ; turn on byte mode
  286.     dw  36000/4     ; page size (dwords)
  287.     dw  360         ; xmax
  288.     dw  400         ; ymax
  289.     dw  0        ; page 1 offset
  290.     dw  0        ; page 2 offset (same as page 1)
  291.     dw  0        ; page 3 offset (same as page 1)
  292.     dw  0        ; page 4 offset (same as page 1)
  293.  
  294. ;****************************************************************************
  295.  
  296. X360x480:
  297.  
  298.     db  0e7h        ; 480 scan lines & 28 mhz clock
  299.     dw  06b00h      ; horz total
  300.     dw  05901h      ; horz displayed
  301.     dw  05a02h      ; start horz blanking
  302.     dw  08e03h      ; end horz blanking
  303.     dw  05e04h      ; start h sync
  304.     dw  08a05h      ; end h sync
  305.     dw  00d06h      ; vertical total
  306.     dw  03e07h      ; overflow
  307.     dw  0ea10h      ; v sync start
  308.     dw  08c11h      ; v sync end/prot cr0 cr7
  309.     dw  0df12h      ; vertical displayed
  310.     dw  0e715h      ; v blank start
  311.     dw  00616h      ; v blank end
  312.     dw  04009h      ; cell height (1 scan line)
  313.     dw  00014h      ; dword mode off
  314.     dw  0e317h      ; turn on byte mode
  315.     dw  43200/4     ; page size (dwords)
  316.     dw  360         ; xmax
  317.     dw  480         ; ymax
  318.     dw  0        ; page 1 offset
  319.     dw  0        ; page 2 offset (same as page 1)
  320.     dw  0        ; page 3 offset (same as page 1)
  321.     dw  0        ; page 4 offset (same as page 1)
  322.  
  323. ;****************************************************************************
  324.  
  325.     attrib_ctrl     equ 03c0h       ; vga attribute controller
  326.     gc_index        equ 03ceh       ; vga graphics controller
  327.     sc_index        equ 03c4h       ; vga sequencer controller
  328.     sc_data         equ 03c5h       ; vga sequencer data port
  329.     crtc_index      equ 03d4h       ; vga crt controller
  330.     crtc_data       equ 03d5h       ; vga crt controller data
  331.     misc_output     equ 03c2h       ; vga misc register
  332.     input_1         equ 03dah       ; input status #1 register
  333.  
  334.     dac_write_addr  equ 03c8h       ; vga dac write addr register
  335.     dac_read_addr   equ 03c7h       ; vga dac read addr register
  336.     pel_data_reg    equ 03c9h       ; vga dac/pel data register r/w
  337.  
  338.     pixel_pan_reg   equ 033h        ; attrib index: pixel pan reg
  339.     map_mask        equ 002h        ; sequ index: write map mask reg
  340.     read_map        equ 004h        ; gc index: read map register
  341.     start_disp_hi   equ 00ch        ; crtc index: display start hi
  342.     start_disp_lo   equ 00dh        ; crtc index: display start lo
  343.  
  344.     map_mask_plane1 equ 00102h      ; map register + plane 1
  345.     map_mask_plane2 equ 01102h      ; map register + plane 1
  346.     all_planes_on   equ 00f02h      ; map register + all bit planes
  347.  
  348.     chain4_off      equ 00604h      ; chain 4 mode off
  349.     async_reset     equ 00100h      ; (a)synchronous reset
  350.     sequ_restart    equ 00300h      ; sequencer restart
  351.  
  352.     latches_on      equ 00008h      ; bit mask + data from latches
  353.     latches_off     equ 0ff08h      ; bit mask + data from cpu
  354.  
  355.     vert_retrace    equ 08h         ; input_1: vertical retrace bit
  356.     plane_bits      equ 03h         ; bits 0-1 of xpos = plane #
  357.     all_planes      equ 0fh         ; all bit planes selected
  358.     char_bits       equ 0fh         ; bits 0-3 of character data
  359.  
  360. ;****************************************************************************
  361.  
  362.     PUBLIC          rows
  363.     PUBLIC          pages
  364.     PUBLIC          xmax
  365.     PUBLIC          ymax
  366.     PUBLIC          vxmin
  367.     PUBLIC          vymin
  368.     PUBLIC          vxmax
  369.     PUBLIC          vymax
  370.  
  371. ;****************************************************************************
  372.  
  373.     rows            dw 800 dup(0)   ; addresses to all rows in the screen
  374.     pages        dw 4   dup(0)    ; offsets of all video pages
  375.     scr_width       dw ?            ; screen width in pixels
  376.     pagesize        dw ?
  377.     xmax            dw ?
  378.     ymax            dw ?
  379.     vxmin           dw ?
  380.     vymin           dw ?
  381.     vxmax           dw ?
  382.     vymax           dw ?
  383.  
  384. ;****************************************************************************
  385.  
  386.     PUBLIC  xinitvideo
  387.  
  388. xinitvideo PROC mode:word
  389.  
  390.     push    ds
  391.     push    es
  392.     push    si
  393.     push    di
  394.  
  395.     and    mode,00000111b          ; make sure mode is in range 0->7
  396.  
  397.     cli
  398.     vwait                           ; wait for start of vertical retrace
  399.     mov    dx,3c8h            ; clear palette to remove flicker
  400.     xor     al,al
  401.     out     dx,al
  402.     inc     dx
  403.     mov     cx,768
  404. xcp1:
  405.     out    dx,al
  406.     loop    xcp1
  407.     vwait
  408.     sti
  409.     mov     ax,0013h                ; set normal 320x200 graphics mode
  410.     int     10h
  411.     cli
  412.     mov    dx,3c8h                 ; clear palette again
  413.     xor     al,al
  414.     out     dx,al
  415.     inc     dx
  416.     mov     cx,768
  417. xcp2:
  418.     out    dx,al
  419.     loop    xcp2
  420.     vwait
  421.  
  422.     out_16  sc_index,chain4_off     ; disable chain 4 mode
  423.     out_16  sc_index,async_reset    ; (a)synchronous reset
  424.     mov     bx,mode                 ; get xmode
  425.     shl     bx,1                    ; multiply it by 2
  426.     mov     si,word ptr xmode[bx]   ; point to Xmode table
  427.     mov     al,byte ptr cs:[si]     ; get crtc data from table
  428.     out_8   misc_output,al          ; set new timing/size
  429.     out_16  sc_index,sequ_restart   ; restart sequencer ...
  430.  
  431.     out_8   crtc_index,11h          ; select vert retrace end register
  432.     inc     dx                      ; point to data
  433.     in      al,dx                   ; get value, bit 7 = protect
  434.     and     al,7fh                  ; mask out write protect
  435.     out     dx,al                   ; and send it back
  436.  
  437.     mov     dx,crtc_index           ; vga crtc registers
  438.     add     si,1                    ; advance pointer
  439.     mov    cx,16            ; we are going to send out 16 words
  440. xiv1:
  441.     mov     ax,word ptr cs:[si]     ; get crtc data from table
  442.     add     si,2                    ; advance pointer
  443.     out     dx,ax                   ; reprogram vga crtc reg
  444.     loop    xiv1                    ; do it 16 times
  445.  
  446.     mov     ax,word ptr cs:[si]     ; get pagesize from table
  447.     mov     pagesize,ax             ; update pagesize var
  448.     mov     ax,word ptr cs:[si+2]   ; get xmax from table
  449.     mov     xmax,ax                 ; update xmax var
  450.     mov    vxmax,ax
  451.     mov     ax,word ptr cs:[si+4]   ; get ymax from table
  452.     mov     ymax,ax                 ; update ymax var
  453.     mov    vymax,ax
  454.     mov     ax,xmax                 ; get xmax
  455.     shr     ax, 2                   ; bytes = pixels / 4
  456.     mov     scr_width, ax           ; save width in bytes
  457.     shr     ax,1                    ; offset value = bytes / 2
  458.     mov     ah,13h                  ; crtc offset register index
  459.     xchg    al,ah                   ; switch format for out
  460.     out     dx,ax                   ; set vga crtc offset reg
  461.  
  462.     mov     cx,800                  ; get # of rows
  463.     mov     bx,offset rows          ; point to rows table
  464.     xor     ax,ax                   ; clear ax
  465. xiv2:
  466.     mov     cs:[bx],ax              ; put row offset in table
  467.     add     ax,scr_width            ; get next row offset
  468.     add     bx,2                    ; advance pointer
  469.     loop    xiv2                    ; loop until i'ts done
  470.  
  471.     mov     ax,cs                   ; get code segment
  472.     mov    ds,ax                   ; load ds with it
  473.     mov    es,ax                   ; and es too
  474.     mov    cx,4                    ; cx=counter=4
  475.     add    si,6                    ; point si to xmode specific pages
  476.     mov     di,offset pages         ; point di to pages table
  477.     rep     movsw                   ; move 4 words from ds:si to es:di
  478.  
  479.     mov    vxmin,0
  480.     mov    vymin,0
  481.  
  482.     sti
  483.  
  484.     pop     di
  485.     pop     si
  486.     pop     es
  487.     pop     ds
  488.  
  489.     ret
  490.  
  491. xinitvideo      ENDP
  492.  
  493. ;****************************************************************************
  494.  
  495.     PUBLIC  xclrvram
  496.  
  497. xclrvram PROC
  498.  
  499.     push    es
  500.     push    di
  501.  
  502.     mov     dx,003c4h       ; update all 4 bit-planes at the same time
  503.     mov     ax,00f02h
  504.     out     dx,ax
  505.  
  506.     cld                     ; block fill forwards
  507.     mov     ax,0a000h       ; clear vram (all planes)
  508.     mov     es,ax
  509.     xor     di,di
  510.     mov     cx,16384
  511.     xor     eax,eax
  512.     rep     stosd
  513.  
  514.     pop     di
  515.     pop     es
  516.  
  517.     ret
  518.  
  519. xclrvram        ENDP
  520.  
  521. ;****************************************************************************
  522.  
  523.     PUBLIC  xclrvpage
  524.  
  525. xclrvpage PROC  vpage:word
  526.  
  527.     push    es
  528.     push    di
  529.  
  530.     mov     ax,0a000h
  531.     mov     es,ax                   ; point to vga memory segment
  532.     mov    bx,vpage                ; get page #
  533.     and    bx,00000011b            ; make sure page # is in range 0->3
  534.     shl    bx,1                    ; scale bx
  535.     mov     di,cs:pages[bx]         ; get page offset
  536.     out_16  sc_index,all_planes_on  ; select all planes
  537.     xor     eax,eax                 ; fill page with color 0
  538.     cld                             ; block fill forwards
  539.     mov     cx,pagesize             ; get size of page
  540.     rep     stosd                   ; block fill vga memory
  541.  
  542.     pop     di
  543.     pop     es
  544.  
  545.     ret
  546.  
  547. xclrvpage       ENDP
  548.  
  549. ;****************************************************************************
  550.  
  551.     PUBLIC  xsetvpage
  552.  
  553. xsetvpage PROC  vpage:word
  554.  
  555.     mov    bx,vpage                ; get page #
  556.     and    bx,00000011b            ; make sure page # is in range 0->3
  557.     shl    bx,1                    ; scale bx
  558.     mov     bx,cs:pages[bx]         ; get page offset
  559.  
  560.     mov     dx,03d4h                ; we change the vga sequencer
  561.  
  562.     mov     al,00ch                 ; display start high register
  563.     mov     ah,bh                   ; high 8 bits of start addr
  564.     out     dx,ax                   ; set display addr high
  565.  
  566.     mov     al,00dh                 ; display start low register
  567.     mov     ah,bl                   ; low 8 bits of start addr
  568.     out     dx,ax                   ; set display addr low
  569.  
  570.     ret
  571.  
  572. xsetvpage       ENDP
  573.  
  574. ;****************************************************************************
  575.  
  576.     PUBLIC     xplot
  577.  
  578. xplot   PROC     x:word, y:word, color:byte, vpage:word
  579.  
  580.     push    es
  581.     push    di
  582.  
  583.     mov     ax,0a000h
  584.     mov     es,ax                   ; point to vga memory segment
  585.  
  586.     mov    bx,vpage                ; get page #
  587.     and    bx,00000011b            ; make sure page # is in range 0->3
  588.     shl    bx,1                    ; scale bx
  589.     mov     di,cs:pages[bx]         ; get page offset
  590.  
  591.     mov    bx,y                    ; get y coord
  592.     shl     bx,1                    ; y=y*2
  593.     add    di,cs:rows[bx]          ; get offset to start of line
  594.  
  595.     mov     bx,x                    ; get x
  596.     mov     cx,bx                   ; copy to extract plane # from
  597.     shr     bx,2                    ; x offset (bytes) = x/4
  598.     add     di,bx                   ; offset = width*y + x/4
  599.  
  600.     mov     ax,map_mask_plane1      ; map mask & plane select register
  601.     and     cl,plane_bits           ; get plane bits
  602.     shl     ah,cl                   ; get plane select value
  603.     out_16  sc_index,ax             ; select plane
  604.  
  605.     mov     al,byte ptr color       ; get pixel color
  606.     mov     byte ptr es:[di],al     ; draw pixel
  607.  
  608.     pop     di
  609.     pop     es
  610.  
  611.     ret
  612.  
  613. xplot ENDP
  614.  
  615. ;****************************************************************************
  616.  
  617.     PUBLIC     xget
  618.  
  619. xget    PROC     x:word, y:word, vpage:word
  620.  
  621.     push    es
  622.     push    di
  623.  
  624.     mov     ax,0a000h
  625.     mov     es,ax                   ; point to vga memory segment
  626.  
  627.     mov    bx,vpage                ; get page #
  628.     and    bx,00000011b            ; make sure page # is in range 0->3
  629.     shl    bx,1                    ; scale bx
  630.     mov     di,cs:pages[bx]         ; get page offset
  631.  
  632.     mov    bx,y                    ; get y coord
  633.     shl     bx,1                    ; y=y*2
  634.     add    di,cs:rows[bx]          ; get offset to start of line
  635.  
  636.     mov     bx,x                    ; get x
  637.     mov     cx,bx                   ; copy to extract plane # from
  638.     shr     bx,2                    ; x offset (bytes) = x/4
  639.     add     di,bx                   ; offset = width*y + x/4
  640.  
  641.     mov     ax,read_map         ; read map register
  642.     and     cl,plane_bits           ; get plane bits
  643.     out_16  gc_index,ax             ; select plane
  644.  
  645.     mov     al,byte ptr es:[di]       ; get pixel color
  646.  
  647.     pop     di
  648.     pop     es
  649.  
  650.     ret
  651.  
  652. xget    ENDP
  653.  
  654. ;****************************************************************************
  655.  
  656. bmpx    dw      ?
  657. bmpy    dw      ?
  658. skew    dw      ?
  659. offi    dw      ?
  660. paste   dw      ?
  661.  
  662. ;****************************************************************************
  663.  
  664.     PUBLIC  ximageput         ; for now ignores remaining 4 or less pixels
  665.  
  666. ximageput PROC     bitmap:dword, x:word, y:word, vpage:word
  667.  
  668.     push    ds
  669.     push    es
  670.     push    si
  671.     push    di
  672.  
  673.     mov     ds,offset bitmap+2      ; get bitmap data segment
  674.     mov     si,offset bitmap        ; get bitmap data offset
  675.     mov     ax,0A000h               ;
  676.     mov     es,ax                   ; point to vga memory segment
  677.  
  678.     mov    bx,vpage                ; get page #
  679.     and    bx,00000011b            ; make sure page # is in range 0->3
  680.     shl    bx,1                    ; scale bx
  681.     mov     di,cs:pages[bx]         ; get page offset
  682.  
  683.     mov    bx,y                    ; get y coord
  684.     shl     bx,1                    ; y=y*2
  685.     add    di,cs:rows[bx]          ; add offset to start of line
  686.     mov     bx,x                    ; get x
  687.     mov     cx,bx                   ; copy to extract plane # from
  688.     xor     ch,ch                   ; ignore high word
  689.     shr     bx,2                    ; x offset (bytes) = x/4
  690.     add     di,bx                   ; add x offset
  691.     mov     offi,di                 ; keep di in var offi for later use
  692.  
  693.     xor     bx,bx                   ; clear bx
  694.  
  695.     lodsw                           ; get bitmap width
  696.     mov     skew,ax                 ; keep it in var skew
  697.     and     skew,00000011b          ; skew now has # of remaining pixels
  698.     shr     ax,2                    ; ax=ax/4
  699.     mov     bmpx,ax                 ; bmpx=bitmap width/4
  700.     lodsw                           ; get bitmap height
  701.     mov     bmpy,ax                 ; keep it in var bmpy
  702.     add     bitmap,4                ; point to bitmap data
  703.     mov    paste,0                 ; clear paste var
  704. xdbmp1:
  705.     inc     ch                      ; ch will be used as a counter (4)
  706.     mov     ax,map_mask_plane1      ; map mask & plane select register
  707.     and     cl,plane_bits           ; get plane bits
  708.     shl     ah,cl                   ; get plane select value
  709.     out_16  sc_index,ax             ; select plane
  710.     push    cx
  711.     call    xdb                     ; draw in it
  712.     pop     cx
  713.     cmp     ch,4                    ; all planes done ?
  714.     je      xdbmp3                  ; if so, end
  715.     cmp     paste,0                 ; are we in a new video ram offset ?
  716.     je      xdbmp2                  ; if not, continue
  717.     add     di,1                    ; if so, inc destination index
  718. xdbmp2:
  719.     add     cl,1                    ; next plane(cl will have plane bits)
  720.     cmp     cl,4                    ; inc plane
  721.     jne     xdbmp1                  ;
  722.     xor     cl,cl
  723.     mov     paste,1
  724.     add     di,1
  725.     jmp     xdbmp1
  726. xdbmp3:
  727.     pop     di
  728.     pop     si
  729.     pop     es
  730.     pop     ds
  731.  
  732.     ret
  733.  
  734. xdb     PROC NEAR
  735.  
  736.     mov     cx,bmpy                 ; loop bmpy times
  737. xdb1:
  738.     push    cx
  739.     mov     cx,bmpx                 ; loop bmpx times
  740. xdb2:
  741.     movsb                           ; plot pixel (and advance 1 pixel)
  742.     add     si,3                    ; advance 3 pixels
  743.     loop    xdb2
  744.     pop     cx
  745.     add     si,skew                 ; step over bitmap skew times
  746.     add     di,scr_width            ; goto next line
  747.     sub     di,bmpx
  748.     loop    xdb1
  749.     mov     di,offi                 ; goto begining vram offset
  750.     inc     bx
  751.     mov     si,offset bitmap        ; point to bitmap data
  752.     add     si,bx                   ; plus bx
  753.  
  754.     ret
  755.  
  756. xdb     ENDP
  757.  
  758. ximageput ENDP
  759.  
  760. ;****************************************************************************
  761.  
  762.     PUBLIC  ximageadd         ; for now ignores remaining 4 or less pixels
  763.  
  764. ximageadd PROC     bitmap:dword, x:word, y:word, vpage:word
  765.  
  766.     push    ds
  767.     push    es
  768.     push    si
  769.     push    di
  770.  
  771.     mov     ds,offset bitmap+2      ; get bitmap data segment
  772.     mov     si,offset bitmap        ; get bitmap data offset
  773.     mov     ax,0A000h               ;
  774.     mov     es,ax                   ; point to vga memory segment
  775.  
  776.     mov    bx,vpage                ; get page #
  777.     and    bx,00000011b            ; make sure page # is in range 0->3
  778.     shl    bx,1                    ; scale bx
  779.     mov     di,cs:pages[bx]         ; get page offset
  780.  
  781.     mov    bx,y                    ; get y coord
  782.     shl     bx,1                    ; y=y*2
  783.     add    di,cs:rows[bx]          ; add offset to start of line
  784.     mov     bx,x                    ; get x
  785.     mov     cx,bx                   ; copy to extract plane # from
  786.     xor     ch,ch                   ; ignore high word
  787.     shr     bx,2                    ; x offset (bytes) = x/4
  788.     add     di,bx                   ; add x offset
  789.     mov     offi,di                 ; keep di in var offi for later use
  790.  
  791.     xor     bx,bx                   ; clear bx
  792.  
  793.     lodsw                           ; get bitmap width
  794.     mov     skew,ax                 ; keep it in var skew
  795.     and     skew,00000011b          ; skew now has # of remaining pixels
  796.     shr     ax,2                    ; ax=ax/4
  797.     mov     bmpx,ax                 ; bmpx=bitmap width/4
  798.     lodsw                           ; get bitmap height
  799.     mov     bmpy,ax                 ; keep it in var bmpy
  800.     add     bitmap,4                ; point to bitmap data
  801.     mov    paste,0                 ; clear paste var
  802. xia1:
  803.     inc     ch                      ; ch will be used as a counter (4)
  804.     mov     ax,map_mask_plane1      ; map mask & plane select register
  805.     and     cl,plane_bits           ; get plane bits
  806.     shl     ah,cl                   ; get plane select value
  807.     out_16  sc_index,ax             ; select plane
  808.  
  809.     mov     al,read_map         ; read map register
  810.     mov    ah,cl
  811.     out_16  gc_index,ax             ; select plane
  812.  
  813.     push    cx
  814.     call    xadd                    ; draw in it
  815.     pop     cx
  816.     cmp     ch,4                    ; all planes done ?
  817.     je      xia3                    ; if so, end
  818.     cmp     paste,0                 ; are we in a new video ram offset ?
  819.     je      xia2                    ; if not, continue
  820.     add     di,1                    ; if so, inc destination index
  821. xia2:
  822.     add     cl,1                    ; next plane(cl will have plane bits)
  823.     cmp     cl,4                    ; inc plane
  824.     jne     xia1                    ;
  825.     xor     cl,cl
  826.     mov     paste,1
  827.     add     di,1
  828.     jmp     xia1
  829. xia3:
  830.     pop     di
  831.     pop     si
  832.     pop     es
  833.     pop     ds
  834.  
  835.     ret
  836.  
  837. xadd    PROC NEAR
  838.  
  839.     mov     cx,bmpy                 ; loop bmpy times
  840. xadd1:
  841.     push    cx
  842.     mov     cx,bmpx                 ; loop bmpx times
  843. xadd2:
  844.     mov    al,es:[di]
  845.     add    al,ds:[si]
  846.     mov     es:[di],al              ; plot pixel
  847.     add     si,4                    ; advance 3 pixels
  848.     add    di,1
  849.     loop    xadd2
  850.     pop     cx
  851.     add     si,skew                 ; step over bitmap skew times
  852.     add     di,scr_width            ; goto next line
  853.     sub     di,bmpx
  854.     loop    xadd1
  855.     mov     di,offi                 ; goto begining vram offset
  856.     inc     bx
  857.     mov     si,offset bitmap        ; point to bitmap data
  858.     add     si,bx                   ; plus bx
  859.  
  860.     ret
  861.  
  862. xadd     ENDP
  863.  
  864. ximageadd ENDP
  865.  
  866. ;****************************************************************************
  867.  
  868.     PUBLIC    xresize
  869.  
  870. xresize PROC     x:word, y:word
  871.  
  872.     mov    ax,x            ; get new screen width
  873.     mov     vxmax,ax                ; save new screen width
  874.     shr     ax,2                    ; bytes = pixels / 4
  875.     mov     scr_width, ax           ; save width in bytes
  876.  
  877.     mov    ax,y                    ; get new screen height
  878.     mov    vymax,ax                ; save new screen height
  879.     mov    cx,800
  880.     mov     bx,offset rows          ; point to rows table
  881.     xor     ax,ax                   ; clear ax
  882. xr1:
  883.     mov     cs:[bx],ax              ; put row offset in table
  884.     add     ax,scr_width            ; get next row offset
  885.     add     bx,2                    ; advance pointer
  886.     loop    xr1                     ; loop until i'ts done
  887.  
  888.     mov    bx,8             ; bx = 8 pixels wide
  889.     mov    ax,x             ; ax = number of pixels per row
  890.     div     bl                  ; al = number of character columms
  891.     xchg    ah,al               ; ah = number of character columms
  892.  
  893.     mov    al,13h                 ; CRTC offset register number
  894.     out_16    crtc_index,ax
  895.  
  896.     ret
  897.  
  898. xresize ENDP
  899.  
  900. ;****************************************************************************
  901.  
  902.     PUBLIC    xpanscr
  903.  
  904. xpanscr    PROC     x:word, y:word
  905.  
  906.     mov    dx,3dah               ; video status port
  907.     in       al,dx                    ; reset flip-flop
  908.     mov      dx,3c0h                 ; attribute controller port
  909.     mov      al,13h or 20h          ; horiz pel pan reg number OR 0x20
  910.     out      dx,al                    ; write attribute controller address reg
  911.     mov      al,byte ptr x           ; get pixel x coordinate
  912.     and      al,3                     ; value for horiz pel pan reg
  913.     shl    al,1
  914.     out      dx,al                    ; write horiz pel pan reg
  915.  
  916.     mov    bx,y            ; get pixel y coordinate
  917.     xor    dx,dx
  918.     mov      ax,x               ; get pixel x coordinate
  919.     div    vxmax
  920.     add    bx,ax
  921.     mov    vymin,bx                ; save new virtual minimum x
  922.     shl    bx,1                    ; scale bx
  923.     mov    bx,cs:rows[bx]          ; get row offset from table
  924.     mov    vxmin,dx                ; save new virtual minimum x
  925.     mov    ax,dx
  926.     shr      ax,2                     ; divide by 4 (for X-mode)
  927.     add      bx,ax                    ; save it for later use
  928.  
  929.     mov      dx,03d4h               ; vga crt controller
  930.     mov      al,0ch            ; start address high reg number
  931.     mov      ah,bh                    ; get start address high
  932.     out      dx,ax                    ; write start address high
  933.  
  934.     mov      al,0dh                  ; start address low reg number
  935.     mov      ah,bl                    ; get start address low
  936.     out      dx,ax                    ; write start address low
  937.  
  938.     ret
  939.  
  940. xpanscr    ENDP
  941.  
  942. ;****************************************************************************
  943.  
  944.     PUBLIC     xsplit
  945.  
  946. xsplit    PROC     n:word
  947.  
  948.     mov    dx,3d4h
  949.     mov    ax,n
  950.     mov    vymax,ax
  951.     mov    bh,ah
  952.     mov    bl,bh
  953.     and    bx,0201h
  954.     mov    cl,4
  955.     shl    bx,cl
  956.     shl    bh,1
  957.     mov    ah,al
  958.     mov    al,18h
  959.     out    dx,ax
  960.     mov    al,7
  961.     out    dx,ax
  962.     inc    dx
  963.     in    al,dx
  964.     dec    dx
  965.     mov    ah,al
  966.     and    ah,11101111b
  967.     or    ah,bl
  968.     mov    al,7
  969.     out    dx,ax
  970.     mov    al,9
  971.     out    dx,al
  972.     inc    dx
  973.     in    al,dx
  974.     dec    dx
  975.     mov    ah,al
  976.     and    ah,10111111b
  977.     or    ah,bh
  978.     mov    al,9
  979.     out    dx,ax
  980.  
  981.     ret
  982.  
  983. xsplit    ENDP
  984.  
  985. ;****************************************************************************
  986.  
  987.     PUBLIC  xlineputcy
  988.  
  989. xlineputcy PROC pointer:dword, ya:word, x:word, y:word, vpage:word
  990.  
  991.     push    ds
  992.     push    es
  993.     push    si
  994.     push    di
  995.  
  996.     mov    ax,0a000h
  997.     mov    es,ax
  998.  
  999.     mov    bx,vpage                ; get page #
  1000.     and    bx,00000011b            ; make sure page # is in range 0->3
  1001.     shl    bx,1                    ; scale bx
  1002.     mov     di,cs:pages[bx]         ; get page offset
  1003.  
  1004.     mov    bx,y                    ; get y coord
  1005.     shl     bx,1                    ; y=y*2
  1006.     add    di,cs:rows[bx]          ; get offset to start of line
  1007.  
  1008.     mov     bx,x                    ; get x
  1009.     mov     cx,bx                   ; copy to extract plane # from
  1010.     shr     bx,2                    ; x offset (bytes) = x/4
  1011.     add     di,bx                   ; offset = width*y + x/4
  1012.  
  1013.     mov     ax,map_mask_plane1      ; map mask & plane select register
  1014.     and     cl,plane_bits           ; get plane bits
  1015.     shl     ah,cl                   ; get plane select value
  1016.     out_16  sc_index,ax             ; select plane
  1017.  
  1018.     mov     si,offset pointer
  1019.     mov     ds,offset pointer+2
  1020.  
  1021.     xor     bx,bx
  1022.     xor     dx,dx
  1023.     xor    cx,cx
  1024. plcy1:
  1025.     mov     cl,byte ptr ds:[si]
  1026.     add     bx,cx
  1027.     mov     al,byte ptr ds:[si+1]
  1028. plcy2:
  1029.     mov     byte ptr es:[di],al
  1030.     add     di,scr_width
  1031.     loop    plcy2
  1032.     add     si,2
  1033.     add     dx,2
  1034.     cmp     bx,ya
  1035.     jl      plcy1
  1036.     mov     ax,dx
  1037.  
  1038.     pop     di
  1039.     pop     si
  1040.     pop     es
  1041.     pop     ds
  1042.  
  1043.     ret
  1044.  
  1045. xlineputcy ENDP
  1046.  
  1047. ;****************************************************************************
  1048.  
  1049.     PUBLIC  xblock
  1050.  
  1051. xblock  PROC     x1:word, y1:word, count:word, y2:word, color:byte, vpage:word
  1052.  
  1053.     push    es
  1054.     push    di
  1055.  
  1056.     mov    ax,0a000h
  1057.     mov    es,ax
  1058.  
  1059.     mov    bx,vpage                ; get page #
  1060.     and    bx,00000011b            ; make sure page # is in range 0->3
  1061.     shl    bx,1                    ; scale bx
  1062.     mov     di,cs:pages[bx]         ; get page offset
  1063.  
  1064.     mov    bx,y1                   ; get y coord
  1065.     shl     bx,1                    ; y=y*2
  1066.     add    di,cs:rows[bx]          ; get offset to start of line
  1067.  
  1068.     mov     bx,x1                   ; get x
  1069.     shr     bx,2                    ; x offset (bytes) = x/4
  1070.     add     di,bx                   ; offset = width*y + x/4
  1071.  
  1072.     mov     dx,003c4h       ; update all 4 bit-planes at the same time
  1073.     mov     ax,00f02h
  1074.     out     dx,ax
  1075.  
  1076.     mov    al,color
  1077.     mov    cx,count
  1078. xb1:
  1079.     push    di
  1080.     push    cx
  1081.     mov    cx,y2
  1082.     sub    cx,y1
  1083. xb2:
  1084.     mov     byte ptr es:[di],al
  1085.     add     di,scr_width
  1086.     loop    xb2
  1087.     pop    cx
  1088.     pop    di
  1089.     inc    di
  1090.     loop    xb1
  1091.  
  1092.     pop     di
  1093.     pop     es
  1094.  
  1095.     ret
  1096.  
  1097. xblock    ENDP
  1098.  
  1099. ;****************************************************************************
  1100.  
  1101.     PUBLIC    xvwait
  1102.  
  1103. xvwait     PROC
  1104.  
  1105.     mov       dx,03DAh
  1106. xvw1:
  1107.     in        al,dx
  1108.     test      al,8
  1109.     jnz     xvw1          ; wait Until out of vertical retrace
  1110. xvw2:
  1111.     in        al,dx
  1112.     test      al,8
  1113.     jz        xvw2           ; wait Until inside vertical retrace
  1114.  
  1115.     ret
  1116.  
  1117. xvwait     ENDP
  1118.  
  1119. ;****************************************************************************
  1120.  
  1121.     PUBLIC    xhwait
  1122.  
  1123. xhwait     PROC
  1124.  
  1125.     mov       dx,03DAh
  1126. xhw1:
  1127.     in        al,dx
  1128.     test      al,1
  1129.     jnz     xhw1          ; wait Until out of vertical retrace
  1130. xhw2:
  1131.     in        al,dx
  1132.     test      al,1
  1133.     jz        xhw1           ; wait Until inside vertical retrace
  1134.  
  1135.     ret
  1136.  
  1137. xhwait     ENDP
  1138.  
  1139. ;******************************************************************************
  1140.  
  1141.     PUBLIC    xsetborder
  1142.  
  1143. xsetborder    PROC color:byte
  1144.  
  1145.     push    ax
  1146.     push    dx
  1147.     cli
  1148.     mov    dx,3dah
  1149.     in    al,dx
  1150.     mov    dx,3c0h
  1151.     mov    al,11h+32
  1152.     out    dx,al
  1153.     mov    al,color
  1154.     out    dx,al
  1155.     sti
  1156.     pop    dx
  1157.     pop    ax
  1158.  
  1159.     ret
  1160.  
  1161. xsetborder     ENDP
  1162.  
  1163. ;******************************************************************************
  1164.  
  1165.     PUBLIC    xsetborder2
  1166.  
  1167. xsetborder2    PROC red:byte, green:byte, blue:byte
  1168.  
  1169.     push    ax
  1170.     push    dx
  1171.     cli
  1172.     mov    dx,3c8h
  1173.         mov     al,0
  1174.         out     dx,al
  1175.         mov     dx,3c9h
  1176.         mov     al,red
  1177.         out     dx,al
  1178.         mov     al,green
  1179.         out     dx,al
  1180.         mov     al,blue
  1181.         out     dx,al
  1182.  
  1183.     sti
  1184.     pop    dx
  1185.     pop    ax
  1186.  
  1187.     ret
  1188.  
  1189. xsetborder2     ENDP
  1190.  
  1191. ;******************************************************************************
  1192.  
  1193.     PUBLIC    xscreenoff
  1194.  
  1195. xscreenoff    PROC mode:byte
  1196.  
  1197.  
  1198.     mov    dx,3dah                 ; reset flip-flop
  1199.     in    al,dx
  1200.     out_8   attrib_ctrl,0           ; disable screen
  1201.  
  1202.     out_8    sc_index,1        ; vga sequencer, index 1
  1203.     inc    dx                      ; vga sequencer data port
  1204.     in      al,dx                   ; get previous settings
  1205.     or      al,00100000b            ; set bit 5 (turn off screen)
  1206.     out     dx,al                   ; restore new settings
  1207.  
  1208.     ret
  1209.  
  1210. xscreenoff     ENDP
  1211.  
  1212. ;******************************************************************************
  1213.  
  1214.     PUBLIC    xscreenon
  1215.  
  1216. xscreenon    PROC mode:byte
  1217.  
  1218.     mov    dx,3dah            ; reset flip-flop
  1219.     in    al,dx
  1220.     out_8   attrib_ctrl,20h         ; enable screen
  1221.  
  1222.     out_8    sc_index,1        ; vga sequencer, index 1
  1223.     inc    dx                      ; vga sequencer data port
  1224.     in      al,dx                   ; get previous settings
  1225.     and      al,11011111b            ; reset bit 5 (turn on screen)
  1226.     out     dx,al                   ; restore new settings
  1227.  
  1228.     ret
  1229.  
  1230. xscreenon         ENDP
  1231.  
  1232. ;******************************************************************************
  1233.  
  1234.     PUBLIC  xsetpalette
  1235.  
  1236. xsetpalette     PROC FAR        pointer: dword
  1237.  
  1238.     push    ds
  1239.     push    si
  1240.  
  1241.     cli
  1242.     mov     cx,256
  1243.     mov     ds,word ptr pointer+2
  1244.     mov     si,word ptr pointer
  1245.     mov     dx,03c8h
  1246.     mov     al,0
  1247.     out     dx,al
  1248.     inc     dx
  1249. sp1:
  1250.     lodsb
  1251.     out     dx,al
  1252.     lodsb
  1253.     out     dx,al
  1254.     lodsb
  1255.     out     dx,al
  1256.     loop    sp1
  1257.     sti
  1258.  
  1259.     pop     si
  1260.     pop     ds
  1261.  
  1262.     ret
  1263.  
  1264. xsetpalette ENDP
  1265.  
  1266. ;******************************************************************************
  1267.  
  1268.     PUBLIC  xgetpalette
  1269.  
  1270. xgetpalette     PROC FAR        firstreg:word, numregs:word, palette:dword
  1271.  
  1272.     push    es
  1273.     push    di
  1274.  
  1275.     mov     cx,numregs
  1276.     jcxz    xgp2
  1277.     les     di,palette
  1278.     cld
  1279.  
  1280.     mov     dx,03C7h
  1281.     mov     ax,firstreg
  1282.     out     dx,al
  1283.     mov     dx,03C9h
  1284.  
  1285. xgp1:
  1286.     in      al,dx
  1287.     shl     al,2
  1288.     stosb                   ; red
  1289.     in      al,dx
  1290.     shl     al,2
  1291.     stosb                   ; green
  1292.     in      al,dx
  1293.     shl     al,2
  1294.     stosb                   ; blue
  1295.     loop    xgp1
  1296.  
  1297. xgp2:
  1298.     pop     di
  1299.     pop    es
  1300.  
  1301.     ret
  1302.  
  1303. xgetpalette ENDP
  1304.  
  1305. ;******************************************************************************
  1306.  
  1307.     PUBLIC  xsetrgb
  1308.  
  1309. xsetrgb         PROC FAR    color:byte, red:byte, green:byte, blue:byte
  1310.  
  1311.     cli
  1312.     mov     dx,03c8h
  1313.     mov     al,color
  1314.     out     dx,al
  1315.     inc     dx
  1316.  
  1317.     mov    al,red
  1318.     out     dx,al
  1319.     mov    al,green
  1320.     out     dx,al
  1321.     mov    al,blue
  1322.     out     dx,al
  1323.     sti
  1324.  
  1325.     ret
  1326.  
  1327. xsetrgb ENDP
  1328.  
  1329. ;******************************************************************************
  1330.  
  1331.     PUBLIC  xtextmode
  1332.  
  1333. xtextmode       PROC FAR    mode:byte
  1334.  
  1335.     mov     ax,03h        ; set text mode
  1336.     int     10h
  1337.  
  1338.     cmp    mode,25       ; 50 lines mode ?
  1339.     je    no50
  1340.  
  1341.     mov     ax,1112h      ; set font height to 8 pixels
  1342.     xor     bx,bx
  1343.     int     10h
  1344. no50:
  1345.     ret
  1346.  
  1347. xtextmode    ENDP
  1348.  
  1349. ;******************************************************************************
  1350.  
  1351. apage     dw ?
  1352.  
  1353. ;******************************************************************************
  1354.  
  1355.     PUBLIC    movewin
  1356.  
  1357. movewin PROC     buffer1:dword, buffer2:dword, vpage:word
  1358.  
  1359.     push    ds
  1360.     push    si
  1361.     push    es
  1362.     push    di
  1363.  
  1364.     mov    ax,0a000h
  1365.     mov    es,ax
  1366.  
  1367.     mov    bx,vpage                ; get page #
  1368.     and    bx,00000011b            ; make sure page # is in range 0->3
  1369.     shl    bx,1                    ; scale bx
  1370.     mov    ax,pages[bx]
  1371.     add    ax,9
  1372.     mov     apage,ax
  1373.  
  1374.     lds    si,buffer1
  1375.     lfs    bx,buffer2
  1376.  
  1377.     mov     dx,003c4h
  1378.     mov     ax,0102h
  1379. mw1:
  1380.     push    ax
  1381.     mov    di,apage             ; get page offset
  1382.     out     dx,ax
  1383.     mov    cx,200
  1384. mw0:
  1385.     push    cx
  1386.     mov    cx,15
  1387. mw2:
  1388.     mov     eax,dword ptr ds:[si]
  1389.     and    eax,dword ptr fs:[bx]
  1390.     mov     dword ptr es:[di],eax
  1391.     add    si,4
  1392.     add    bx,4
  1393.     add    di,4
  1394.     loop    mw2
  1395.     pop    cx
  1396.     add    di,20
  1397.     add    si,20
  1398.     add    bx,20
  1399.     loop    mw0
  1400.     mov    ax,ds
  1401.     add    ax,405
  1402.     mov    ds,ax
  1403.     mov    ax,fs
  1404.     add    ax,405
  1405.     mov    fs,ax
  1406.     pop    ax
  1407.     shl    ah,1
  1408.     cmp    ah,8
  1409.     jbe    mw1
  1410.  
  1411.     pop     di
  1412.     pop     es
  1413.     pop     si
  1414.     pop     ds
  1415.  
  1416.     ret
  1417.  
  1418. movewin ENDP
  1419.  
  1420.  
  1421. END
  1422.